/*******************************************************************
 *  Copyright(c) 2022-2025 Ltd.
 *  All right reserved. See LGPL for detailed Information
 *
 *  文件名称: qohfunctions.cpp
 *  简要描述: 提供鸿蒙Native开发的辅助接口函数
 *  创建日期: 2024/11/06
 *  作者: WangHao
 *  说明:
 *
 *  修改日期: 2025/1/14
 *  作者: WangHao
 *  说明: 添加接口
 *  requestPermissionsOnSetting
 *  requestPermissionsOnSettingSync
 ******************************************************************/
#include <QDebug>
#include <QJsModule>
#include <qopenharmony.h>

#include "qohfunctions.h"
#include "qpa/qplatformaccessctrl.h"
#include "qpa/qplatformintegration.h"
#include "private/qguiapplication_p.h"

QT_BEGIN_NAMESPACE

namespace QtOh {
static PermissionRequestResult privateToPublicPermissionsResult(const QtOhPrivate::PermissionRequestResult &result)
{
    QList<PermissionResult> convertedAuthResults;
    for (const auto& authResult : result.authResults) {
        switch (authResult) {
        case QtOhPrivate::PermissionsResult::Denied:
            convertedAuthResults.append(PermissionResult::Denied);
            break;
        case QtOhPrivate::PermissionsResult::Granted:
            convertedAuthResults.append(PermissionResult::Granted);
            break;
        case QtOhPrivate::PermissionsResult::InValidRequest:
            convertedAuthResults.append(PermissionResult::InValidRequest);
            break;
        default:
            convertedAuthResults.append(PermissionResult::InValidRequest);
            break;
        }
    }

    return QtOh::PermissionRequestResult(
            result.permissions,
            convertedAuthResults,
            result.dialogShownResults
            );
}

int ohSdkVersion()
{
#if 0
    /* @hms.core.atomicserviceComponent.atomicservice还能获取主题等信息 */
    int version = -1;
    QJsModule sysModule("@hms.core.atomicserviceComponent.atomicservice");
    Napi::Array sysInfoTypes = Napi::Array::New(sysModule.env());
    sysInfoTypes.Set(uint32_t(0), std::string("sdkApiVersion"));

    Napi::Object info = sysModule.call("getSystemInfoSync", { sysInfoTypes }).As<Napi::Object>();
    if (!info.IsNull()) {
        version = info.Get("sdkApiVersion").ToNumber();
    }
    return version;
#endif
    return QtOh::apiVersion();
}

PermissionResult checkPermission(const QString &permission)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return PermissionResult{ -1 };
    }
    int result = accessCtrl->checkPermission(permission);
    return PermissionResult{ result };
}

PermissionRequestResult requestPermissionsSync(const QStringList &permissions, int timeoutMs)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return PermissionRequestResult();
    }

    QtOhPrivate::PermissionRequestResult privateResult = accessCtrl->requestPermissionsSync(permissions, timeoutMs);
    return privateToPublicPermissionsResult(privateResult);
}

void requestPermissions(const QStringList &permissions, const PermissionResultCallback &callbackFunc)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return;
    }

    accessCtrl->requestPermissions(permissions, [callbackFunc](const QtOhPrivate::PermissionRequestResult &result){
        callbackFunc(privateToPublicPermissionsResult(result));
    });
}

PermissionRequestResult requestPermissionsOnSettingSync(const QStringList &permissions, int timeoutMs)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return PermissionRequestResult();
    }

    QtOhPrivate::PermissionRequestResult privateResult = accessCtrl->requestPermissionsOnSettingSync(permissions, timeoutMs);
    return privateToPublicPermissionsResult(privateResult);
}

void requestPermissionsOnSetting(const QStringList &permissions, const PermissionResultCallback &callbackFunc)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return;
    }

    accessCtrl->requestPermissionsOnSetting(permissions, [callbackFunc](const QtOhPrivate::PermissionRequestResult &result){
        callbackFunc(privateToPublicPermissionsResult(result));
    });
}

void requestEnableNotification(const enableNotificationFunc &callbackFunc)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return;
    }

    accessCtrl->requestEnableNotification([callbackFunc](bool result){
        callbackFunc(result);
    });
}

bool requestEnableNotificationSync(int timeoutMs)
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return false;
    }

    return accessCtrl->requestEnableNotificationSync(timeoutMs);
}

bool isNotificationEnabled()
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return false;
    }

    return accessCtrl->isNotificationEnabled();
}

void openNotificationSettings()
{
    QPlatformAccessCtrl *accessCtrl = QGuiApplicationPrivate::platformIntegration()->accessCtrl();
    if (nullptr == accessCtrl) {
        qWarning() << Q_FUNC_INFO << "get QPlatformAccessCtrl failed.";
        return;
    }

    accessCtrl->openNotificationSettings();
}

}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QtOh::PermissionRequestResult &result)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    dbg.noquote();

    dbg << "PermissionRequestResult(";
    dbg << "permissions: " << result.permissions << ", ";
    dbg << "authResults: [";
    for (int i = 0; i < result.authResults.size(); ++i) {
        if (i > 0) dbg << ", ";
        switch (result.authResults[i]) {
        case QtOh::PermissionResult::Denied:
            dbg << "Denied";
            break;
        case QtOh::PermissionResult::Granted:
            dbg << "Granted";
            break;
        case QtOh::PermissionResult::InValidRequest:
            dbg << "InValidRequest";
            break;
        default:
            dbg << "Unknown";
            break;
        }
    }
    dbg << "], ";
    dbg << "dialogShownResults: " << result.dialogShownResults; /* 打印 dialogShownResults */
    dbg << ")";

    return dbg;
}
#endif

QT_END_NAMESPACE
